﻿using LightCAD.Core.Elements;
using System.Text.Json.Serialization;

namespace LightCAD.Core
{
    [JsonDerivedType(typeof(ModelSpace), typeDiscriminator: nameof(ModelSpace))]
    [JsonDerivedType(typeof(Block), typeDiscriminator: nameof(Block))]

    public class ElementContainer : LcadObject
    {
        /// <summary>
        /// 所有元素集合，IElementContainer成员
        /// </summary>
        [JsonInclude]
        public ElementCollection Elements { get; internal set; }

        [JsonIgnore]
        public bool IsFireChangedEvent { get; set; } = true;

        public ClipAreaCollection ClipAreas { get; set; }

        public void InsertElement(Element element)
        {
            if (this.Elements == null)
            {
                this.Elements = new ElementCollection();
            }
            element.Parent = this;
            if (!IsFireChangedEvent)
            {
                element.Document = this.Document;
                this.Elements.Add(element);
            }
            else
            {
                var args = new ObjectChangedEventArgs
                {
                    Type = ObjectChangeType.Insert,
                    Target = element
                };
                this.Document.OnObjectChangedBefore(args);
                if (args.IsCancel) return;
                element.Document = this.Document;
                this.Elements.Add(element);
                this.Document.OnObjectChangedAfter(args);
            }

        }
        public bool RemoveElement(Element element)
        {
            if (this.Elements == null || this != element.Parent)
            {
                throw new ArgumentException(SR.ElementNotInContainer, nameof(element));
            }
            if (!this.Elements.Contains(element))
            {
                return false;
            }
            if (!IsFireChangedEvent)
            {
                this.Elements.Remove(element);
                return true;
            }
            else
            {
                var args = new ObjectChangedEventArgs
                {
                    Type = ObjectChangeType.Remove,
                    Target = element
                };
                this.Document.OnObjectChangedBefore(args);
                if (args.IsCancel) return false;
                this.Elements.Remove(element);
                this.Document.OnObjectChangedAfter(args);
                return true;
            }

        }

        public void MoveElement(Element element,double dx,double dy)
        {
            element.Translate(dx, dy);
        }
        public Circle AddCircle(Vector2d center, double radius)
        {
            var circle = this.Document.CreateObject<Circle>();
            circle.Center = center;
            circle.Radius = radius;
            this.InsertElement(circle);
            return circle;
        }
        public Line AddLine(Vector2d start, Vector2d end)
        {
            var line = this.Document.CreateObject<Line>();
            line.Start = start;
            line.End = end;
            this.InsertElement(line);
            return line;
        }
    }
}
